<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>深拷贝</title>
  </head>
  <body></body>
  <script>
    // 手写深拷贝----正则等问题
    const sym = Symbol('sym')
    const obj = {
      a: 1,
      b: 2,
      date: new Date(),
      regExp: /hahaha/gi,
      [sym]: 'sym', // sym作为键
    }
    obj.c = obj
    const deepClone = (source, clonedMap = new Map()) => {
      // 基本类型直接返回
      if (typeof source !== 'object' || source === null) {
        return source
      }
      // 如果存在则直接返回
      if (clonedMap.has(source)) {
        return clonedMap.get(source)
      }
      let target
      if (Array.isArray(source)) {
        target = []
      } else if (source instanceof Date) {
        target = new Date(source)
      } else if (source instanceof RegExp) {
        target = new RegExp(source.source, source.flags)
      } else {
        target = {}
      }
      // 在Map中记录这个对象
      clonedMap.set(source, target)
      // 遍历普通属性
      for (const key in source) {
        // if (Object.hasOwnProperty.call(source, key)) {  //是否需要原型链上属性
        if (typeof source[key] === 'object' && source[key] !== null) {
          target[key] = deepClone(source[key], clonedMap)
        } else {
          target[key] = source[key]
        }
        // }
      }
      // 遍历Symbol属性
      const symbolKeys = Object.getOwnPropertySymbols(source)
      for (const symKey of symbolKeys) {
        target[symKey] = deepClone(source[symKey], clonedMap)
      }
      return target
    }
    const copyObj = deepClone(obj)
    console.log(copyObj)
  </script>
</html>
